package com.xqboss.web.controller.order;

import cn.hutool.core.bean.BeanUtil;
import com.xqboss.apps.convert.order.OrderConverter;
import com.xqboss.apps.convert.user.UserConverter;
import com.xqboss.apps.domain.order.OrderMain;
import com.xqboss.apps.domain.order.PayApply;
import com.xqboss.apps.dto.PageDto;
import com.xqboss.apps.dto.order.OrderStatisticsDto;
import com.xqboss.apps.dto.order.WebOrderListDto;
import com.xqboss.apps.enums.nft.NftDispatchSourceEnum;
import com.xqboss.apps.mapper.consumer.ConsumerRealNameMapper;
import com.xqboss.apps.service.order.NftDispatchRecordService;
import com.xqboss.apps.service.order.OrderService;
import com.xqboss.apps.service.order.PayApplyService;
import com.xqboss.apps.vo.order.AppOrderListExportVo;
import com.xqboss.apps.vo.order.AppOrderListVo;
import com.xqboss.apps.vo.order.OrderStatisticsVo;
import com.xqboss.apps.vo.order.WebOrderDetailVo;
import com.xqboss.apps.vo.sys.SysUserVo;
import com.xqboss.apps.vo.sys.WebSysUserInfoVo;
import com.xqboss.apps.vo.user.UserNFTItemVo;
import com.xqboss.common.annotation.Log;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.PageList;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.enums.BusinessType;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.LocalDateUtils;
import com.xqboss.common.utils.poi.ExcelUtil;
import com.xqboss.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 订单控制器
 * </p>
 *
 * @author Trent
 * @date 2023/8/23
 */
@Slf4j
@Api(tags = "订单-用户订单管理")
@RestController("WebOrderController")
@RequestMapping("/web/order")
public class OrderController extends BaseController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private NftDispatchRecordService nftRecordService;

    @Autowired
    private OrderConverter orderConverter;

    @Autowired
    private PayApplyService payApplyService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private UserConverter userConverter;

    @Autowired
    private ConsumerRealNameMapper consumerRealNameMapper;

    //    @ApiOperation("获取订单统计信息")
    @GetMapping("statistics")
    public R<OrderStatisticsVo> getStatistics(@Validated OrderStatisticsDto params) {
        OrderStatisticsVo vo = orderService.getStatistics(params);
        return R.ok(vo);
    }

    @PreAuthorize("@ss.hasPermi('web:order:list')")
    @ApiOperation("列表")
    @GetMapping("list")
    public R<List<AppOrderListVo>> list(@Validated WebOrderListDto request) {
        PageList<AppOrderListVo> page = orderService.getOrderListV2(request);
        return R.ok(page);
    }

    @PreAuthorize("@ss.hasPermi('web:order:detail')")
    @ApiOperation("详情")
    @GetMapping("detail/{orderId}")
    public R<WebOrderDetailVo> detail(@Validated @PathVariable("orderId")
                    @ApiParam(value = "订单号", required = true)
                    @NotNull(message = "订单号不能为空")
                    Long orderId) {
        OrderMain orderDetail = orderService.getOrderDetail(orderId, null);
        List<UserNFTItemVo> nftRecord = nftRecordService.getRecordByOrderId(NftDispatchSourceEnum.ORDER, orderDetail.getId());
        PayApply payApply = null;
        if(Objects.nonNull(orderDetail.getPayOrderNo())){
            // 如果支付流水不为空，则获取支付信息
            payApply = payApplyService.getById(orderDetail.getPayOrderNo());
        }
        WebSysUserInfoVo sysUserVo = consumerRealNameMapper.findByKey(orderDetail.getBuyerUserId());

        WebOrderDetailVo detailVo = orderConverter.toWebOrderDetailVo(orderDetail, nftRecord);

        detailVo.setBuyerInfo(BeanUtil.copyProperties(sysUserVo, SysUserVo.class));
        if (Objects.nonNull(orderDetail.getSellerUserId())) {
            WebSysUserInfoVo sellerUser = consumerRealNameMapper.findByKey(orderDetail.getSellerUserId());
            detailVo.setSellerUserInfo(BeanUtil.copyProperties(sellerUser, SysUserVo.class));
        }
        detailVo.setPayInfo(payApply);
        return R.ok(detailVo);
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:order:cancel')")
    @GetMapping("cancel/{orderId}")
    @Log(title = "订单", businessType = BusinessType.UPDATE)
    public R cancel(@Validated @PathVariable("orderId")
                                      @ApiParam(value = "订单号", required = true)
                                      @NotNull(message = "订单号不能为空")
                                      Long orderId) {
        orderService.cancel(orderId, null);
        return R.ok();
    }


    @PreAuthorize("@ss.hasPermi('web:order:pay-list')")
    @ApiOperation("获取订单支付记录")
    @GetMapping("pay-list/{orderId}")
    public R<List<PayApply>> payList(@Validated @PathVariable("orderId")
                    @ApiParam(value = "订单号", required = true)
                    @NotNull(message = "订单号不能为空")
                    Long orderId, @Validated PageDto params) {
        params.startPageAndOrder();
        List<PayApply> payList = payApplyService.getOrderPayList(orderId);
        return R.ok(payList);
    }


    /**
     * 订单导出（充值订单，市场订单，藏品宝盒订单）
     */
    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:user:recharge:export')")
    @ApiOperation("订单导出（充值订单，市场订单，藏品宝盒订单）")
    @Log(title = "订单导出（充值订单，市场订单，藏品宝盒订单）", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(@Validated WebOrderListDto request, HttpServletResponse response) {
        if (Objects.isNull(request) || Objects.isNull(request.getCreateTimeStart()) || Objects.isNull(request.getCreateTimeEnd())) {
            throw new ServiceException("请选择开始时间/结束时间");
        }
        if (LocalDateUtils.getDifferentDays(request.getCreateTimeStart().toLocalDate(), request.getCreateTimeEnd().toLocalDate()) > 7) {
            throw new ServiceException("开始结束时间不能超过7天");
        }
        List<AppOrderListExportVo> list = orderService.export(request);
        ExcelUtil<AppOrderListExportVo> util = new ExcelUtil<>(AppOrderListExportVo.class);
        util.exportExcel(response, list, "订单导出（充值订单，市场订单，藏品宝盒订单）");
    }
}
